package com.mairuide.transactionstreamcount.service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.mairuide.bill.dto.DealFlowDto;
import com.mairuide.casemanage.service.CaseManageService;

/**
 * Created by 敲代码的卡卡罗特
 * on 2018/12/13 14:19.
 */
@Service
@Transactional(readOnly = true)
public class TransactionStreamD3Service {
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private CaseManageService caseManageService;
    
    /**
     * 流入卡号D3统计
     * @param dealFlowdto
     * @return
     */
    public Map<String, Object> getInStreamAccountD3(DealFlowDto dealFlowdto){
        String whichTable = caseManageService.getWhichTable(dealFlowdto.getCasemanageId());
        StringBuffer sb=new StringBuffer();
        sb.append("SELECT df.* ");
        sb.append("  FROM (");
        sb.append(" SELECT max(ACCOUNT_BODY) AS ACCOUNT_BODY,ACCOUNT_BODY_CARD,max(BODY_TYPE) AS BODY_TYPE,MAX(ACCOUNT_RIVAL) AS ACCOUNT_RIVAL,account_rival_card,SUM( abs(account_money) ) AS totalMoney,COUNT( account_rival_card ) AS totalNumber,");
        sb.append(" COALESCE( sum( CASE WHEN sign = '0' THEN abs(account_money) END ), 0 ) AS inMoney,");
        sb.append(" COUNT( CASE WHEN sign = '0' THEN account_money END ) AS inNumber");
        sb.append(" FROM "+whichTable+" WHERE casemanage_id = '"+dealFlowdto.getCasemanageId()+"'");
        if(StringUtils.isNotBlank(dealFlowdto.getCardList())){
            if (!"-1".equals(dealFlowdto.getCardList())) sb.append(" AND account_body_card in ( "+dealFlowdto.getCardList()+" )");
        }else{
            sb.append(" AND account_body_card in ( NULL )");
        }
        if(StringUtils.isNotBlank(dealFlowdto.getMinMoney())){
            sb.append(" AND account_money >="+dealFlowdto.getMinMoney());
        }
        if(StringUtils.isNotBlank(dealFlowdto.getMaxMoney())){
            sb.append(" AND account_money <="+dealFlowdto.getMaxMoney());
        }
        if (StringUtils.isNotBlank(dealFlowdto.getAccountRival())){
            sb.append(" AND account_rival like '%"+dealFlowdto.getAccountRival()+"%'");
        }
        if (StringUtils.isNotBlank(dealFlowdto.getBeginTime())){
            sb.append(" AND to_char(TRADE_DATE,'yyyy-mm-dd') >= '"+dealFlowdto.getBeginTime()+"'");
        }
        if (StringUtils.isNotBlank(dealFlowdto.getEndTime())){
            sb.append(" AND to_char(TRADE_DATE,'yyyy-mm-dd') <= '"+dealFlowdto.getEndTime()+"'");
        }
        sb.append(" GROUP BY ACCOUNT_BODY_CARD,account_rival_card ) df where  df.TOTALMONEY>0  AND df.TOTALNUMBER>0 and df.inNumber>0 ORDER BY ROWNUM DESC");
        List<Map<String, Object>> maps = jdbcTemplate.queryForList(sb.toString());
        Map<String, Object> hashMap = new HashMap<>();
        if (maps.size()>0){
            List<String> selectedCards = Arrays.asList(dealFlowdto.getCardList().split(","));//所有已选单位的合集 -1代表全选
            
            List<Map<String, Object>> nodes = new ArrayList<Map<String, Object>>();
            List<Map<String, Object>> links = new ArrayList<Map<String, Object>>();
            List<String> nodeNameList = new ArrayList<String>();
            for (int i=0;i<maps.size();i++){
                /** 封装交易主题D3 **/
                encapsulationAccountBodyD3(dealFlowdto, selectedCards, nodes, nodeNameList, maps.get(i));
            }

            for (int i=0;i<maps.size();i++){
            	/** 封装交易对手D3 **/
                encapsulationAccountRivalD3(maps, nodes, nodeNameList, i);
            }
            /** 封装交易主体交易对手line start**/
            for (int i=0;i<maps.size();i++){
                Map<String, Object> map = maps.get(i);
                HashMap<String, Object> link = new HashMap<>();
                String nodeName = map.get("ACCOUNT_BODY")==null?(map.get("ACCOUNT_BODY_CARD").toString()):(map.get("ACCOUNT_BODY").toString());
                String nodeName2 = map.get("ACCOUNT_RIVAL")==null?(map.get("ACCOUNT_RIVAL_CARD").toString()):(map.get("ACCOUNT_RIVAL").toString());
                for (Map<String, Object> m:nodes){
                    if (nodeName2.equals((String)m.get("name"))){
                    	link.put("node1",m.get("id"));
                    }
                    if (nodeName.equals((String)m.get("name"))){
                    	link.put("node2",m.get("id"));
                    }
                    link.put("name","交易"+map.get("INNUMBER")+"次,转入"+map.get("INMONEY")+"元");
                }
                if(!link.keySet().contains("node1")||!link.keySet().contains("node2")) continue;
                links.add(link);
            }
            /** 封装交易主体交易对手line end**/
            
            hashMap.put("links",links);
            hashMap.put("nodes",nodes);
        }

        return hashMap;
    }
    
    /**
     * 流出卡号D3统计
     * @param dealFlowdto
     * @return
     */
    public Map<String, Object> getOutStreamAccountD3(DealFlowDto dealFlowdto){
        String whichTable = caseManageService.getWhichTable(dealFlowdto.getCasemanageId());
        StringBuffer sb=new StringBuffer();
        sb.append("SELECT df.* ");
        sb.append(" FROM (");
        sb.append(" SELECT max(ACCOUNT_BODY) AS ACCOUNT_BODY,ACCOUNT_BODY_CARD,max(BODY_TYPE) AS BODY_TYPE,MAX(ACCOUNT_RIVAL) AS ACCOUNT_RIVAL,account_rival_card,SUM( abs(account_money) ) AS totalMoney,COUNT( account_rival_card ) AS totalNumber,");
        sb.append(" COALESCE( sum( CASE WHEN sign = '1' THEN abs(account_money) END ), 0 ) AS outMoney,");
        sb.append(" COUNT( CASE WHEN sign = '1' THEN account_money END ) AS outNumber ");
        sb.append(" FROM "+whichTable+" WHERE casemanage_id = '"+dealFlowdto.getCasemanageId()+"'");
        if(StringUtils.isNotBlank(dealFlowdto.getCardList())){
            if (!"-1".equals(dealFlowdto.getCardList())) {
            	sb.append(" AND account_body_card in ( "+dealFlowdto.getCardList()+" )");
            }
        }else{
            sb.append(" AND account_body_card in ( NULL )");
        }
        if(StringUtils.isNotBlank(dealFlowdto.getMinMoney())){
            sb.append(" AND account_money >="+dealFlowdto.getMinMoney());
        }
        if(StringUtils.isNotBlank(dealFlowdto.getMaxMoney())){
            sb.append(" AND account_money <="+dealFlowdto.getMaxMoney());
        }
        if (StringUtils.isNotBlank(dealFlowdto.getAccountRival())){
            sb.append(" AND account_rival like '%"+dealFlowdto.getAccountRival()+"%'");
        }
        if (StringUtils.isNotBlank(dealFlowdto.getBeginTime())){
            sb.append(" AND to_char(TRADE_DATE,'yyyy-mm-dd') >= '"+dealFlowdto.getBeginTime()+"'");
        }
        if (StringUtils.isNotBlank(dealFlowdto.getEndTime())){
            sb.append(" AND to_char(TRADE_DATE,'yyyy-mm-dd') <= '"+dealFlowdto.getEndTime()+"'");
        }
        sb.append(" GROUP BY ACCOUNT_BODY_CARD,account_rival_card ) df where  df.TOTALMONEY>0  AND df.TOTALNUMBER>0 and df.outNumber>0 ORDER BY ROWNUM DESC");
        List<Map<String, Object>> maps = jdbcTemplate.queryForList(sb.toString());

        Map<String, Object> hashMap = new HashMap<>();
        if(maps.size()>0){
        	List<String> selectedCards = Arrays.asList(dealFlowdto.getCardList().split(","));//所有已选单位的合集 -1代表全选
            
            List<Map<String, Object>> nodes = new ArrayList<Map<String, Object>>();
            List<Map<String, Object>> links = new ArrayList<Map<String, Object>>();
            List<String> nodeNameList = new ArrayList<String>();
            for (int i=0;i<maps.size();i++){
                /** 封装交易主题D3 **/
                encapsulationAccountBodyD3(dealFlowdto, selectedCards, nodes, nodeNameList, maps.get(i));
            }

            for (int i=0;i<maps.size();i++){
            	/** 封装交易对手D3 **/
                encapsulationAccountRivalD3(maps, nodes, nodeNameList, i);
            }
            
            /** 封装交易主体交易对手line **/
            for (int i=0;i<maps.size();i++){
                Map<String, Object> map = maps.get(i);
                HashMap<String, Object> link = new HashMap<>();
                String nodeName = map.get("ACCOUNT_BODY")==null?(map.get("ACCOUNT_BODY_CARD").toString()):(map.get("ACCOUNT_BODY").toString());
                String nodeName2 = map.get("ACCOUNT_RIVAL")==null?(map.get("ACCOUNT_RIVAL_CARD").toString()):(map.get("ACCOUNT_RIVAL").toString());
                for (Map<String, Object> m:nodes){
                    if (nodeName2.equals((String)m.get("name"))){
                    	link.put("node1",m.get("id"));
                    }
                    if (nodeName.equals((String)m.get("name"))){
                    	link.put("node2",m.get("id"));
                    }
                    link.put("name","交易"+map.get("OUTNUMBER")+"次,转出"+map.get("OUTMONEY")+"元");
                }
                if(!link.keySet().contains("node1")||!link.keySet().contains("node2")) continue;
                links.add(link);
            }
            /** 封装交易主体交易对手line end**/
            
            hashMap.put("links",links);
            hashMap.put("nodes",nodes);
        }
        return hashMap;
    }
    
    /**
     * 流入主体统计关系D3
     * @param dealFlowdto
     * @return
     */
    public Map<String, Object> getInStreamBodyD3(DealFlowDto dealFlowdto){
        String whichTable = caseManageService.getWhichTable(dealFlowdto.getCasemanageId());
        StringBuffer sb=new StringBuffer();
        sb.append("SELECT df.*, ");
        sb.append(" concat( ROUND( df.inMoney / df.totalMoney * 100, 2 ), '%' )  AS inMoneyPer,");
        sb.append(" concat( ROUND( df.outMoney / df.totalMoney * 100, 2 ), '%' )  AS outMoneyPer,");
        sb.append(" abs(df.inMoney - df.outMoney) AS PureInMoney,");
        sb.append(" abs(df.outMoney - df.inMoney) AS PureOutMoney,");
        sb.append(" concat( ROUND( df.outNumber / df.totalNumber * 100, 2 ), '%' )  AS outNumberPer,");
        sb.append(" concat( ROUND( df.inNumber / df.totalNumber * 100, 2 ), '%' )  AS inNumberPer FROM (");
        sb.append(" SELECT ACCOUNT_BODY_CARD,account_rival,SUM( abs(account_money) ) AS totalMoney,COUNT( account_rival_card ) AS totalNumber,");
        sb.append(" COALESCE( sum( CASE WHEN sign = '0' THEN abs(account_money) END ), 0 ) AS inMoney,");
        sb.append(" COALESCE( sum( CASE WHEN sign = '1' THEN abs(account_money) END ), 0 ) AS outMoney,");
        sb.append(" COUNT( CASE WHEN sign = '0' THEN account_money END ) AS inNumber,");
        sb.append(" COUNT( CASE WHEN sign = '1' THEN account_money END ) AS outNumber ");
        sb.append(" FROM "+whichTable+" WHERE casemanage_id = '"+dealFlowdto.getCasemanageId()+"' AND account_rival is not NULL ");
        if(StringUtils.isNotBlank(dealFlowdto.getCardList())){
            if (dealFlowdto.getCardList().split(",").length<1000)
                sb.append(" AND account_body_card in ( "+dealFlowdto.getCardList()+" )");
        }else{
            sb.append(" AND account_body_card in ( NULL )");
        }
        if(StringUtils.isNotBlank(dealFlowdto.getMinMoney())){
            sb.append(" AND account_money >="+dealFlowdto.getMinMoney());
        }
        if(StringUtils.isNotBlank(dealFlowdto.getMaxMoney())){
            sb.append(" AND account_money <="+dealFlowdto.getMaxMoney());
        }
        if (StringUtils.isNotBlank(dealFlowdto.getAccountRival())){
            sb.append(" AND account_rival like '%"+dealFlowdto.getAccountRival()+"%'");
        }
        if (StringUtils.isNotBlank(dealFlowdto.getBeginTime())){
            sb.append(" AND to_char(TRADE_DATE,'yyyy-mm-dd') >= '"+dealFlowdto.getBeginTime()+"'");
        }
        if (StringUtils.isNotBlank(dealFlowdto.getEndTime())){
            sb.append(" AND to_char(TRADE_DATE,'yyyy-mm-dd') <= '"+dealFlowdto.getEndTime()+"'");
        }
        sb.append(" GROUP BY ACCOUNT_BODY_CARD,account_rival) df where df.TOTALMONEY>0  AND df.TOTALNUMBER>0 and df.inNumber>0 ORDER BY ROWNUM DESC");
        List<Map<String, Object>> maps = jdbcTemplate.queryForList(sb.toString());

        Map<String, Object> hashMap = new HashMap<>();
        if (maps.size()>0){
            String cardList = dealFlowdto.get_checkedAccount();
            String[] split = cardList.split(",");
            Set<Object> set_ACCOUNT_BODY_CARD = maps.stream().map(m -> m.get("ACCOUNT_BODY_CARD")).collect(Collectors.toSet());
            List<String> collect = new ArrayList<String>(new HashSet(Arrays.stream(split).map(m -> m.split("_")[0]).collect(Collectors.toList())));
            List<String> collect2 = new ArrayList<String>(new HashSet(Arrays.stream(split).map(m -> m.split("_")[1]).collect(Collectors.toSet())));
            List<Map<String, Object>> nodes = new ArrayList<Map<String, Object>>();
            List<Map<String, Object>> links = new ArrayList<Map<String, Object>>();
            for (int i=0;i<collect.size();i++){
                if (set_ACCOUNT_BODY_CARD.contains(collect2.get(i))){
                    HashMap<String, Object> node_map = new HashMap<>();
                    node_map.put("id",UUID.randomUUID().toString());
                    node_map.put("name",collect.get(i));
                    node_map.put("width",100);
                    node_map.put("height",100);
                    node_map.put("image","/plugins/d3/image/body1.png");
                    nodes.add(node_map);
                }
            }
            for (int i=0;i<maps.size();i++){
                Map<String, Object> stringObjectMap = maps.get(i);
                List<String> RIVAL_CARD_list = nodes.stream().map(m ->(String) m.get("name")).collect(Collectors.toList());
                if (!RIVAL_CARD_list.contains(stringObjectMap.get("ACCOUNT_RIVAL").toString())){
                    HashMap<String, Object> node_map = new HashMap<>();
                    node_map.put("id",UUID.randomUUID().toString());
                    node_map.put("name",stringObjectMap.get("ACCOUNT_RIVAL").toString());
                    node_map.put("width",60);
                    node_map.put("height",60);
                    node_map.put("image","/plugins/d3/image/ka1.png");
                    nodes.add(node_map);
                }
            }


            for (int i=0;i<maps.size();i++){
                Map<String, Object> stringObjectMap = maps.get(i);
                HashMap<String, Object> links_map = new HashMap<>();
                String account_rival = (String)stringObjectMap.get("ACCOUNT_RIVAL");
                String account_body_card = (String)stringObjectMap.get("ACCOUNT_BODY_CARD");
                for (String s:split){
                    if (s.contains(account_body_card)){
                        account_body_card=s.split("_")[0];
                    }
                }
                for (Map<String, Object> m:nodes){
                    if (account_rival.equals((String)m.get("name"))){
                        links_map.put("node1",m.get("id"));
                    }
                    if (account_body_card.equals((String)m.get("name"))){
                        links_map.put("node2",m.get("id"));
                    }
                    links_map.put("name","交易"+stringObjectMap.get("INNUMBER")+"次,转入"+stringObjectMap.get("INMONEY")+"元");
                }
                if(!links_map.keySet().contains("node1")||!links_map.keySet().contains("node2")) continue;
                links.add(links_map);
            }
            hashMap.put("links",links);
            hashMap.put("nodes",nodes);

        }
        return hashMap;
    }

    public Map getOutStreamBodyD3( DealFlowDto dealFlowdto){
        String whichTable = caseManageService.getWhichTable(dealFlowdto.getCasemanageId());
        StringBuffer sb=new StringBuffer();
        sb.append("SELECT df.*, ");
        sb.append(" concat( ROUND( df.inMoney / df.totalMoney * 100, 2 ), '%' )  AS inMoneyPer,");
        sb.append(" concat( ROUND( df.outMoney / df.totalMoney * 100, 2 ), '%' )  AS outMoneyPer,");
        sb.append(" abs(df.inMoney - df.outMoney) AS PureInMoney,");
        sb.append(" abs(df.outMoney - df.inMoney) AS PureOutMoney,");
        sb.append(" concat( ROUND( df.outNumber / df.totalNumber * 100, 2 ), '%' )  AS outNumberPer,");
        sb.append(" concat( ROUND( df.inNumber / df.totalNumber * 100, 2 ), '%' )  AS inNumberPer FROM (");
        sb.append(" SELECT ACCOUNT_BODY_CARD,account_rival,SUM( abs(account_money) ) AS totalMoney,COUNT( account_rival_card ) AS totalNumber,");
        sb.append(" COALESCE( sum( CASE WHEN sign = '0' THEN abs(account_money) END ), 0 ) AS inMoney,");
        sb.append(" COALESCE( sum( CASE WHEN sign = '1' THEN abs(account_money) END ), 0 ) AS outMoney,");
        sb.append(" COUNT( CASE WHEN sign = '0' THEN account_money END ) AS inNumber,");
        sb.append(" COUNT( CASE WHEN sign = '1' THEN account_money END ) AS outNumber ");
        sb.append(" FROM "+whichTable+" WHERE casemanage_id = '"+dealFlowdto.getCasemanageId()+"' AND account_rival is not NULL ");
        if(StringUtils.isNotBlank(dealFlowdto.getCardList())){
            if (dealFlowdto.getCardList().split(",").length<1000)
                sb.append(" AND account_body_card in ( "+dealFlowdto.getCardList()+" )");
        }else{
            sb.append(" AND account_body_card in ( NULL )");
        }
        if(StringUtils.isNotBlank(dealFlowdto.getMinMoney())){
            sb.append(" AND account_money >="+dealFlowdto.getMinMoney());
        }
        if(StringUtils.isNotBlank(dealFlowdto.getMaxMoney())){
            sb.append(" AND account_money <="+dealFlowdto.getMaxMoney());
        }
        if (StringUtils.isNotBlank(dealFlowdto.getAccountRival())){
            sb.append(" AND account_rival like '%"+dealFlowdto.getAccountRival()+"%'");
        }
        if (StringUtils.isNotBlank(dealFlowdto.getBeginTime())){
            sb.append(" AND to_char(TRADE_DATE,'yyyy-mm-dd') >= '"+dealFlowdto.getBeginTime()+"'");
        }
        if (StringUtils.isNotBlank(dealFlowdto.getEndTime())){
            sb.append(" AND to_char(TRADE_DATE,'yyyy-mm-dd') <= '"+dealFlowdto.getEndTime()+"'");
        }
        sb.append(" GROUP BY ACCOUNT_BODY_CARD,account_rival) df where  df.TOTALMONEY>0  AND df.TOTALNUMBER>0 and df.outNumber>0 ORDER BY ROWNUM DESC");
        List<Map<String, Object>> maps = jdbcTemplate.queryForList(sb.toString());

        Map<String, Object> hashMap = new HashMap<>();
        if (maps.size()>0){
            String cardList = dealFlowdto.get_checkedAccount();
            String[] split = cardList.split(",");
            Set<Object> set_ACCOUNT_BODY_CARD = maps.stream().map(m -> m.get("ACCOUNT_BODY_CARD")).collect(Collectors.toSet());
            List<String> collect=new ArrayList<>(new HashSet(Arrays.stream(split).map(m -> m.split("_")[0]).collect(Collectors.toList())));
            List<String> collect2=new ArrayList<>(new HashSet(Arrays.stream(split).map(m -> m.split("_")[1]).collect(Collectors.toSet())));
            List<Map<String, Object>> nodes = new ArrayList<Map<String, Object>>();
            List<Map<String, Object>> links = new ArrayList<Map<String, Object>>();
            for (int i=0;i<collect.size();i++){
                if (set_ACCOUNT_BODY_CARD.contains(collect2.get(i))){
                    HashMap<String, Object> node_map = new HashMap<>();
                    node_map.put("id",UUID.randomUUID().toString());
                    node_map.put("name",collect.get(i));
                    node_map.put("width",100);
                    node_map.put("height",100);
                    node_map.put("image","/plugins/d3/image/body1.png");
                    nodes.add(node_map);
                }
            }
            for (int i=0;i<maps.size();i++){
                Map<String, Object> stringObjectMap = maps.get(i);
                List<String> RIVAL_CARD_list = nodes.stream().map(m ->(String) m.get("name")).collect(Collectors.toList());
                if (!RIVAL_CARD_list.contains(stringObjectMap.get("ACCOUNT_RIVAL").toString())){
                    HashMap<String, Object> node_map = new HashMap<>();
                    node_map.put("id",UUID.randomUUID().toString());
                    node_map.put("name",stringObjectMap.get("ACCOUNT_RIVAL").toString());
                    node_map.put("width",60);
                    node_map.put("height",60);
                    node_map.put("image","/plugins/d3/image/ka1.png");
                    nodes.add(node_map);
                }
            }


            for (int i=0;i<maps.size();i++){
                Map<String, Object> stringObjectMap = maps.get(i);
                HashMap<String, Object> links_map = new HashMap<>();
                String account_rival = (String)stringObjectMap.get("ACCOUNT_RIVAL");
                String account_body_card = (String)stringObjectMap.get("ACCOUNT_BODY_CARD");
                for (String s:split){
                    if (s.contains(account_body_card)){
                        account_body_card=s.split("_")[0];
                    }
                }
                for (Map<String, Object> m:nodes){
                    if (account_rival.equals((String)m.get("name"))){
                        links_map.put("node1",m.get("id"));
                    }
                    if (account_body_card.equals((String)m.get("name"))){
                        links_map.put("node2",m.get("id"));
                    }
                    links_map.put("name","交易"+stringObjectMap.get("OUTNUMBER")+"次,转出"+stringObjectMap.get("OUTMONEY")+"元");
                }
                if(!links_map.keySet().contains("node1")||!links_map.keySet().contains("node2")) continue;
                links.add(links_map);
            }
            hashMap.put("links",links);
            hashMap.put("nodes",nodes);

        }
        return hashMap;
    }
    
    /**
     * 封装交易主题D3
     * @param maps
     * @param nodes
     * @param nodeNameList
     * @param i
     */
	private void encapsulationAccountRivalD3(List<Map<String, Object>> maps, List<Map<String, Object>> nodes,
			List<String> nodeNameList, int i) {
		Map<String, Object> map = maps.get(i);
		//封装交易对手 多循环一次是为了先封装交易主体，再封装对手
		String nodeName2 = map.get("ACCOUNT_RIVAL")==null?(map.get("ACCOUNT_RIVAL_CARD").toString()):(map.get("ACCOUNT_RIVAL").toString());
		String nodeCard2 = map.get("ACCOUNT_RIVAL_CARD")==null?"":map.get("ACCOUNT_RIVAL_CARD").toString();
		if (!nodeNameList.contains(nodeName2)){
		    HashMap<String, Object> node = new HashMap<>();
		    node.put("id",UUID.randomUUID().toString());
		    node.put("name",nodeName2);
		    node.put("card",nodeCard2);
		    node.put("isSpecial", "0");
			node.put("width",60);
			node.put("height",60);
			// 判断账户名称是否包含企业或公司
		    if(com.mairuide._frame.utils.StringUtils.isNotEmpty(nodeName2) && com.mairuide._frame.utils.StringUtils.isNotEmpty(nodeCard2)) {
		    	if(nodeName2.contains("企业") || nodeName2.contains("公司") 
		    			|| nodeName2.contains("支付宝") || nodeName2.contains("财付通")
		    			|| nodeCard2.length() == 15 || nodeCard2.length() == 17) {
		    		node.put("image","/plugins/d3/image/q1.png");
		    	}else {
		    		node.put("image","/plugins/d3/image/r1.png");
		    	}
		    }else {
		    	node.put("image","/plugins/d3/image/r1.png");
		    }
			
		    nodes.add(node);
		    nodeNameList.add(nodeName2);
		}
	}
	
	/**
	 * 封装交易对手D3
	 * @param dealFlowdto
	 * @param selectedCards
	 * @param nodes
	 * @param nodeNameList
	 * @param map
	 */
	private void encapsulationAccountBodyD3(DealFlowDto dealFlowdto, List<String> selectedCards,
			List<Map<String, Object>> nodes, List<String> nodeNameList, Map<String, Object> map) {
		String nodeName = map.get("ACCOUNT_BODY")==null?(map.get("ACCOUNT_BODY_CARD").toString()):(map.get("ACCOUNT_BODY").toString());
		String nodeCard = map.get("ACCOUNT_BODY_CARD")==null?"":map.get("ACCOUNT_BODY_CARD").toString();
		String isSpecial = (map.get("BODY_TYPE")!=null && "嫌疑人".equals(map.get("BODY_TYPE").toString()))?"1":"0";
		if (!nodeNameList.contains(nodeName)){
		    HashMap<String, Object> node = new HashMap<>();
		    node.put("id",UUID.randomUUID().toString());
		    node.put("name",nodeName);
		    node.put("card",nodeCard);
		    node.put("isSpecial", isSpecial);
		    if("-1".equals(dealFlowdto.getCardList()) || selectedCards.contains("'"+nodeCard+"'")) {
		    	node.put("width",100);
		    	node.put("height",100);
		    }else {
		    	node.put("width",60);
		    	node.put("height",60);
		    }
		    // 判断账户名称是否包含企业或公司
		    if(com.mairuide._frame.utils.StringUtils.isNotEmpty(nodeName) && com.mairuide._frame.utils.StringUtils.isNotEmpty(nodeCard)) {
		    	if(nodeName.contains("企业") || nodeName.contains("公司") 
		    			|| nodeName.contains("支付宝") || nodeName.contains("财付通")
		    			|| nodeCard.length() == 15 || nodeCard.length() == 17 ) {
		    		if(isSpecial.equals("1")) {
		    			//嫌疑单位账户
		        		node.put("image","/plugins/d3/image/q2.png");
		    		}else {
		    			node.put("image","/plugins/d3/image/q1.png");
		    		}
		    	}else {
		    		if(isSpecial.equals("1")) {
		    			//嫌疑人账户
		        		node.put("image","/plugins/d3/image/r2.png");
		    		}else {
		    			node.put("image","/plugins/d3/image/r1.png");
		    		}
		    	}
		    }else {
		    	node.put("image","/plugins/d3/image/r1.png");
		    }
		    nodes.add(node);
		    nodeNameList.add(nodeName);
		}
	}

	/**
     * 获取流入流出树
     * @param dealFlowdto
     * @return
     */
    public Map<String, Object> getInD3Tree(DealFlowDto dealFlowdto){
        String whichTable = caseManageService.getWhichTable(dealFlowdto.getCasemanageId());
        Map<String, Object> hashMap = new HashMap<String, Object>();
        Map<String, Object> rootNode = new HashMap<String, Object>();
        if("-1".equals(dealFlowdto.getCardList())) {
        	rootNode.put("name", "全部");
        }else {
        	if(StringUtils.isNotBlank(dealFlowdto.getCardList())){
        		String bodySql = "select a.* from (select max(ACCOUNT_BODY) as ACCOUNT_BODY,ACCOUNT_BODY_CARD from "+whichTable+" where is_delete=0 and casemanage_id='"+dealFlowdto.getCasemanageId()+"' and account_body_card in ( "+dealFlowdto.getCardList()+" ) group by account_body_card) a order by account_body,account_body_card asc";
        		List<Map<String, Object>> bodyList = jdbcTemplate.queryForList(bodySql);
        		if(bodyList!=null && bodyList.size()>0) {
        			String name="";
        			for(Map<String, Object> map:bodyList) {
        				if(map.get("ACCOUNT_BODY")!=null) {
        					name += map.get("ACCOUNT_BODY").toString();
        				}
        				if(map.get("ACCOUNT_BODY_CARD")!=null) {
        					name = name + " " + map.get("ACCOUNT_BODY_CARD").toString()+",";
        				}
        			}
        			if(name.endsWith(",")) {
        				name = name.substring(0,name.length()-1);
        			}
            		rootNode.put("name", name);
        		}
        	}else {
            	rootNode.put("name", "无");
        	}
        }
        String rootId = UUID.randomUUID().toString();
        rootNode.put("id",rootId);
        
        List<Map<String, Object>> childNodes = new ArrayList<Map<String, Object>>();
        List<Map<String, Object>> links = new ArrayList<Map<String, Object>>();
        //资金流入
        StringBuffer inSql = new StringBuffer();
        inSql.append("select * from (select account_rival || ' ' || account_rival_card as NAME,sum(abs(account_money)) as TOTALMONEY from "+whichTable+" WHERE casemanage_id = '"+dealFlowdto.getCasemanageId()+"' and is_delete=0 and sign=0 ");
        //资金流出
        StringBuffer outSql = new StringBuffer();
        outSql.append("select * from (select account_rival || ' ' || account_rival_card as NAME,sum(abs(account_money)) as TOTALMONEY from "+whichTable+" WHERE casemanage_id = '"+dealFlowdto.getCasemanageId()+"' and is_delete=0 and sign=1 ");
        if(StringUtils.isNotBlank(dealFlowdto.getCardList())){
            if (!"-1".equals(dealFlowdto.getCardList())) {
            	inSql.append(" AND account_body_card in ( "+dealFlowdto.getCardList()+" )");
            	inSql.append(" AND account_rival_card not in ( "+dealFlowdto.getCardList()+" )");
            	outSql.append(" AND account_body_card in ( "+dealFlowdto.getCardList()+" )");
            	outSql.append(" AND account_rival_card not in ( "+dealFlowdto.getCardList()+" )");
            }else {
            	inSql.append(" AND account_rival_card not in ( select distinct account_body_card from "+whichTable+" WHERE casemanage_id = '"+dealFlowdto.getCasemanageId()+"' and is_delete=0 )");
            	outSql.append(" AND account_rival_card not in ( select distinct account_body_card from "+whichTable+" WHERE casemanage_id = '"+dealFlowdto.getCasemanageId()+"' and is_delete=0 )");
            }
        }else{
        	inSql.append(" AND account_body_card in ( NULL )");
        	outSql.append(" AND account_body_card in ( NULL )");
        }
        if(StringUtils.isNotBlank(dealFlowdto.getMinMoney())){
        	inSql.append(" AND account_money >="+dealFlowdto.getMinMoney());
        	outSql.append(" AND account_money >="+dealFlowdto.getMinMoney());
        }
        if(StringUtils.isNotBlank(dealFlowdto.getMaxMoney())){
        	inSql.append(" AND account_money <="+dealFlowdto.getMaxMoney());
        	outSql.append(" AND account_money <="+dealFlowdto.getMaxMoney());
        }
        if (StringUtils.isNotBlank(dealFlowdto.getAccountRival())){
        	inSql.append(" AND account_rival like '%"+dealFlowdto.getAccountRival()+"%'");
        	outSql.append(" AND account_rival like '%"+dealFlowdto.getAccountRival()+"%'");
        }
        if (StringUtils.isNotBlank(dealFlowdto.getBeginTime())){
        	inSql.append(" AND to_char(TRADE_DATE,'yyyy-mm-dd') >= '"+dealFlowdto.getBeginTime()+"'");
        	outSql.append(" AND to_char(TRADE_DATE,'yyyy-mm-dd') >= '"+dealFlowdto.getBeginTime()+"'");
        }
        if (StringUtils.isNotBlank(dealFlowdto.getEndTime())){
        	inSql.append(" AND to_char(TRADE_DATE,'yyyy-mm-dd') <= '"+dealFlowdto.getEndTime()+"'");
        	outSql.append(" AND to_char(TRADE_DATE,'yyyy-mm-dd') <= '"+dealFlowdto.getEndTime()+"'");
        }
        inSql.append(" group by account_rival || ' ' || account_rival_card order by totalmoney desc) a where rownum<31");
        outSql.append(" group by account_rival || ' ' || account_rival_card order by totalmoney desc) a where rownum<31");
        
        //流入账号分析主要分析流入对象，所以先封装流入信息
        Map<String, Object> nodenameMap = new HashMap<String, Object>();
        List<Map<String, Object>> records1 = jdbcTemplate.queryForList(inSql.toString());
        if(records1!=null && records1.size()>0) {
        	for(Map<String, Object> in:records1) {
        		String name = in.get("NAME")==null?"未知":in.get("NAME").toString();
        		Map<String, Object> node = new HashMap<String,Object>();
        		String uuid=UUID.randomUUID().toString();
        		node.put("id",uuid);
        		node.put("name", name);
        		node.put("float", "left");
        		node.put("parentlinename", "金额"+(in.get("TOTALMONEY")));
        		childNodes.add(node);
        		nodenameMap.put(name, uuid);
        	}
        }
        //再分析流出对象，记得虑重
        List<Map<String, Object>> records2 = jdbcTemplate.queryForList(outSql.toString());
        if(records2!=null && records2.size()>0) {
        	for(Map<String, Object> out:records2) {
        		String name = out.get("NAME")==null?"未知":out.get("NAME").toString();
        		if(nodenameMap.get(name)==null) {
        			Map<String, Object> node = new HashMap<String,Object>();
            		String uuid=UUID.randomUUID().toString();
        			node.put("id",uuid);
        			node.put("name", name);
        			node.put("parentlinename", "金额"+(out.get("TOTALMONEY")));
        			childNodes.add(node);
            		nodenameMap.put(name, uuid);
        		}else {
        			Map<String, Object> link = new HashMap<String, Object>();
        			link.put("node1", rootId);
        			link.put("node2", nodenameMap.get(name));
        			link.put("name", "金额"+(out.get("TOTALMONEY")));
        			links.add(link);
        		}
        	}
        }

	    rootNode.put("children",childNodes);
        hashMap.put("links",links);
        hashMap.put("nodes",rootNode);
        return hashMap;
    }
    
    /**
     * 获取流入流出树
     * @param dealFlowdto
     * @return
     */
    public Map<String, Object> getOutD3Tree(DealFlowDto dealFlowdto){
    	String whichTable = caseManageService.getWhichTable(dealFlowdto.getCasemanageId());
    	Map<String, Object> hashMap = new HashMap<String, Object>();
    	Map<String, Object> rootNode = new HashMap<String, Object>();
    	if("-1".equals(dealFlowdto.getCardList())) {
    		rootNode.put("name", "全部");
    	}else {
    		if(StringUtils.isNotBlank(dealFlowdto.getCardList())){
        		String bodySql = "select distinct ACCOUNT_BODY,ACCOUNT_BODY_CARD from "+whichTable+" where is_delete=0 and casemanage_id='"+dealFlowdto.getCasemanageId()+"' and account_body_card in ( "+dealFlowdto.getCardList()+" ) order by account_body,account_body_card asc";
        		List<Map<String, Object>> bodyList = jdbcTemplate.queryForList(bodySql);
        		if(bodyList!=null && bodyList.size()>0) {
        			String name="";
        			for(Map<String, Object> map:bodyList) {
        				if(map.get("ACCOUNT_BODY")!=null) {
        					name += map.get("ACCOUNT_BODY").toString();
        				}
        				if(map.get("ACCOUNT_BODY_CARD")!=null) {
        					name = name + " " + map.get("ACCOUNT_BODY_CARD").toString()+",";
        				}
        			}
        			if(name.endsWith(",")) {
        				name = name.substring(0,name.length()-1);
        			}
            		rootNode.put("name", name);
        		}
        	}else {
            	rootNode.put("name", "无");
        	}
    	}
    	String rootId = UUID.randomUUID().toString();
    	rootNode.put("id",rootId);
    	
    	List<Map<String, Object>> childNodes = new ArrayList<Map<String, Object>>();
    	List<Map<String, Object>> links = new ArrayList<Map<String, Object>>();
    	//资金流入
    	StringBuffer inSql = new StringBuffer();
    	inSql.append("select * from (select account_rival || ' ' || account_rival_card as NAME,sum(abs(account_money)) as TOTALMONEY from "+whichTable+" WHERE casemanage_id = '"+dealFlowdto.getCasemanageId()+"' and is_delete=0 and sign=0 ");
    	//资金流出
    	StringBuffer outSql = new StringBuffer();
    	outSql.append("select * from (select account_rival || ' ' || account_rival_card as NAME,sum(abs(account_money)) as TOTALMONEY from "+whichTable+" WHERE casemanage_id = '"+dealFlowdto.getCasemanageId()+"' and is_delete=0 and sign=1 ");
    	if(StringUtils.isNotBlank(dealFlowdto.getCardList())){
    		if (!"-1".equals(dealFlowdto.getCardList())) {
    			inSql.append(" AND account_body_card in ( "+dealFlowdto.getCardList()+" )");
    			inSql.append(" AND account_rival_card not in ( "+dealFlowdto.getCardList()+" )");
    			outSql.append(" AND account_body_card in ( "+dealFlowdto.getCardList()+" )");
    			outSql.append(" AND account_rival_card not in ( "+dealFlowdto.getCardList()+" )");
    		}else {
    			inSql.append(" AND account_rival_card not in ( select distinct account_body_card from "+whichTable+" WHERE casemanage_id = '"+dealFlowdto.getCasemanageId()+"' and is_delete=0 )");
    			outSql.append(" AND account_rival_card not in ( select distinct account_body_card from "+whichTable+" WHERE casemanage_id = '"+dealFlowdto.getCasemanageId()+"' and is_delete=0 )");
    		}
    	}else{
    		inSql.append(" AND account_body_card in ( NULL )");
    		outSql.append(" AND account_body_card in ( NULL )");
    	}
    	if(StringUtils.isNotBlank(dealFlowdto.getMinMoney())){
    		inSql.append(" AND account_money >="+dealFlowdto.getMinMoney());
    		outSql.append(" AND account_money >="+dealFlowdto.getMinMoney());
    	}
    	if(StringUtils.isNotBlank(dealFlowdto.getMaxMoney())){
    		inSql.append(" AND account_money <="+dealFlowdto.getMaxMoney());
    		outSql.append(" AND account_money <="+dealFlowdto.getMaxMoney());
    	}
    	if (StringUtils.isNotBlank(dealFlowdto.getAccountRival())){
    		inSql.append(" AND account_rival like '%"+dealFlowdto.getAccountRival()+"%'");
    		outSql.append(" AND account_rival like '%"+dealFlowdto.getAccountRival()+"%'");
    	}
    	if (StringUtils.isNotBlank(dealFlowdto.getBeginTime())){
    		inSql.append(" AND to_char(TRADE_DATE,'yyyy-mm-dd') >= '"+dealFlowdto.getBeginTime()+"'");
    		outSql.append(" AND to_char(TRADE_DATE,'yyyy-mm-dd') >= '"+dealFlowdto.getBeginTime()+"'");
    	}
    	if (StringUtils.isNotBlank(dealFlowdto.getEndTime())){
    		inSql.append(" AND to_char(TRADE_DATE,'yyyy-mm-dd') <= '"+dealFlowdto.getEndTime()+"'");
    		outSql.append(" AND to_char(TRADE_DATE,'yyyy-mm-dd') <= '"+dealFlowdto.getEndTime()+"'");
    	}
    	inSql.append(" group by account_rival || ' ' || account_rival_card order by totalmoney desc) a where rownum<31");
    	outSql.append(" group by account_rival || ' ' || account_rival_card order by totalmoney desc) a where rownum<31");
    	
    	//流出账号分析主要分析流出对象，所以先封装流出信息
    	Map<String, Object> nodenameMap = new HashMap<String, Object>();
    	List<Map<String, Object>> records2 = jdbcTemplate.queryForList(outSql.toString());
    	if(records2!=null && records2.size()>0) {
    		for(Map<String, Object> out:records2) {
    			String name = out.get("NAME")==null?"未知":out.get("NAME").toString();
    			Map<String, Object> node = new HashMap<String,Object>();
    			String uuid=UUID.randomUUID().toString();
    			node.put("id",uuid);
    			node.put("name", name);
    			node.put("parentlinename", "金额"+(out.get("TOTALMONEY")));
    			childNodes.add(node);
    			nodenameMap.put(name, uuid);
    		}
    	}
    	
    	//再分析流入对象，记得虑重
    	List<Map<String, Object>> records1 = jdbcTemplate.queryForList(inSql.toString());
    	if(records1!=null && records1.size()>0) {
    		for(Map<String, Object> in:records1) {
    			String name = in.get("NAME")==null?"未知":in.get("NAME").toString();
    			if(nodenameMap.get(name)==null) {
    				Map<String, Object> node = new HashMap<String,Object>();
    				String uuid=UUID.randomUUID().toString();
    				node.put("id",uuid);
    				node.put("name", name);
        			node.put("float", "left");
    				node.put("parentlinename", "金额"+(in.get("TOTALMONEY")));
    				childNodes.add(node);
    				nodenameMap.put(name, uuid);
    			}else {
    				Map<String, Object> link = new HashMap<String, Object>();
    				link.put("node1", nodenameMap.get(name));
    				link.put("node2", rootId);
    				link.put("name", "金额"+(in.get("TOTALMONEY")));
    				links.add(link);
    			}
    		}
    	}
    	
    	rootNode.put("children",childNodes);
    	hashMap.put("links",links);
    	hashMap.put("nodes",rootNode);
    	return hashMap;
    }
}
